package com.acdc.wechat.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 微信支付V3解密测试工具
 * 用于测试和调试微信支付通知的解密问题
 */
public class WechatPayV3DecryptTester {
    
    private static final Logger log = LoggerFactory.getLogger(WechatPayV3DecryptTester.class);
    
    /**
     * 测试解密功能
     */
    public static void testDecryption() {
        log.info("=== 开始微信支付V3解密测试 ===");
        
        // 使用实际的测试数据（从日志中获取）
        String testCiphertext = "OqnfGcErZsQ6LdVgBZBlph3Gx77H+Jmcg/z1/JXP37RwKmAAJOOPcS00ZZSGbjiqju6mhG09nBbuoQGqFSwSrBCDtQObxs3xSFxNU4h/3tgy/HzIieEjjxle5d6VYAnREgL6xJyi56x06/iCFe2wcpGwBmq2goN68SJexGLWUTbrhlPnulUhteC++pjgEDba7McHjv4Hi7UMdTwrMIZcJbUZvNjUMf/ikMwRdsCNWNh9rdSyizOF6yWKEAu563xh3PobTNbw5xI+h0p+Lj3W8aOSrvhuHFOmfuG8VvYEZebEAxPRE/Q3Cy47zIXf354sE0GoNQCiL08mlIKrEypz7dK5EZei65ZTxXlRKM+FL6p298UxzyJiVHEKfnF9S17D8S9XXbhVEyL8jsZ338BPC3uGpj/dqpzWpu8mbmlIfFOKV6Wuf/06DOAfT4l3Rr9tNVbrX8BM048JwIsSJIPH8GCA0Q1iMdMRQTfIr1g7o/ccPdp3kKrRLSgfDal3G5L8zYnhPvK4DmQi+dTq6QczbGJ8Rf7WTpUqjkJB0c7Z7yecqcApBgVkvuHlFCErOwexhW59pw==";
        String testAssociatedData = "transaction";
        String testNonce = "hEdxtB7iMgLe";
        String testApiV3Key = "2z7Q9Xp4Rk8Lm3Fb5Gs1Hj6Nv0Tc4Yw2"; // 从配置文件获取
        
        log.info("测试数据:");
        log.info("  ciphertext长度: {}", testCiphertext.length());
        log.info("  associatedData: '{}'", testAssociatedData);
        log.info("  nonce: '{}'", testNonce);
        log.info("  apiV3Key长度: {}", testApiV3Key.length());
        
        // 测试1：标准解密方式
        testStandardDecryption(testCiphertext, testAssociatedData, testNonce, testApiV3Key);
        
        // 测试2：备用解密方式
        testFallbackDecryption(testCiphertext, testAssociatedData, testNonce, testApiV3Key);
        
        log.info("=== 微信支付V3解密测试完成 ===");
    }
    
    /**
     * 测试标准解密方式
     */
    private static void testStandardDecryption(String ciphertext, String associatedData, String nonce, String apiV3Key) {
        try {
            log.info("--- 测试标准解密方式 ---");
            
            // 检查参数格式
            log.info("检查ciphertext是否为Base64编码: {}", isValidBase64(ciphertext));
            log.info("检查nonce是否为Base64编码: {}", isValidBase64(nonce));
            
            // 尝试解密
            String result = WechatPayDecryptUtil.decrypt(ciphertext, associatedData, nonce, apiV3Key);
            log.info("✓ 标准解密成功: {}", result);
            
        } catch (Exception e) {
            log.error("✗ 标准解密失败: {}", e.getMessage());
        }
    }
    
    /**
     * 测试备用解密方式
     */
    private static void testFallbackDecryption(String ciphertext, String associatedData, String nonce, String apiV3Key) {
        try {
            log.info("--- 测试备用解密方式 ---");
            
            String result = WechatPayDecryptUtil.decryptWithFallback(ciphertext, associatedData, nonce, apiV3Key);
            log.info("✓ 备用解密成功: {}", result);
            
        } catch (Exception e) {
            log.error("✗ 备用解密也失败: {}", e.getMessage());
            
            // 尝试手动解密
            testManualDecryption(ciphertext, associatedData, nonce, apiV3Key);
        }
    }
    
    /**
     * 测试手动解密方式
     */
    private static void testManualDecryption(String ciphertext, String associatedData, String nonce, String apiV3Key) {
        try {
            log.info("--- 测试手动解密方式 ---");
            
            AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
            
            // 方式1：直接使用原始参数
            try {
                log.info("尝试方式1：直接使用原始参数");
                byte[] ciphertextBytes = Base64.getDecoder().decode(ciphertext);
                byte[] associatedDataBytes = associatedData.getBytes(StandardCharsets.UTF_8);
                
                String result = aesUtil.decryptToString(ciphertextBytes, associatedDataBytes, nonce);
                log.info("✓ 方式1成功: {}", result);
                return;
            } catch (Exception e1) {
                log.warn("方式1失败: {}", e1.getMessage());
            }
            
            // 方式2：将nonce进行Base64编码
            try {
                log.info("尝试方式2：将nonce进行Base64编码");
                byte[] ciphertextBytes = Base64.getDecoder().decode(ciphertext);
                byte[] associatedDataBytes = associatedData.getBytes(StandardCharsets.UTF_8);
                String encodedNonce = Base64.getEncoder().encodeToString(nonce.getBytes(StandardCharsets.UTF_8));
                
                String result = aesUtil.decryptToString(ciphertextBytes, associatedDataBytes, encodedNonce);
                log.info("✓ 方式2成功: {}", result);
                return;
            } catch (Exception e2) {
                log.warn("方式2失败: {}", e2.getMessage());
            }
            
            // 方式3：尝试不同的字符编码
            try {
                log.info("尝试方式3：使用ISO-8859-1编码");
                byte[] ciphertextBytes = Base64.getDecoder().decode(ciphertext);
                byte[] associatedDataBytes = associatedData.getBytes("ISO-8859-1");
                
                String result = aesUtil.decryptToString(ciphertextBytes, associatedDataBytes, nonce);
                log.info("✓ 方式3成功: {}", result);
                return;
            } catch (Exception e3) {
                log.warn("方式3失败: {}", e3.getMessage());
            }
            
            log.error("所有手动解密方式都失败");
            
        } catch (Exception e) {
            log.error("手动解密测试失败", e);
        }
    }
    
    /**
     * 验证字符串是否为有效的Base64编码
     */
    private static boolean isValidBase64(String str) {
        if (str == null || str.trim().isEmpty()) {
            return false;
        }
        
        try {
            Base64.getDecoder().decode(str);
            return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
    
    /**
     * 主方法，用于独立测试
     */
    public static void main(String[] args) {
        log.info("微信支付V3解密测试工具启动");
        
        // 运行解密测试
        testDecryption();
        
        log.info("解密测试工具运行完成");
    }
}
